package wf.source.hrm.service.impl;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import wf.source.hrm.domain.Course;
import wf.source.hrm.domain.CourseDetail;
import wf.source.hrm.domain.CourseMarket;
import wf.source.hrm.domain.CourseResource;
import wf.source.hrm.es.doc.EsCourse;
import wf.source.hrm.es.repository.EsCourseRepository;
import wf.source.hrm.mapper.*;
import wf.source.hrm.query.CourseQuery;
import wf.source.hrm.service.ICourseService;
import wf.source.hrm.util.PageList;

import java.io.Serializable;
import java.math.BigDecimal;
import java.util.*;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author wangfang
 * @since 2020-06-26
 */
@Service
public class CourseServiceImpl extends ServiceImpl<CourseMapper, Course> implements ICourseService {
    @Autowired
    private CourseMapper courseMapper;
    @Autowired
    private CourseMarketMapper courseMarketMapper;
    @Autowired
    private CourseDetailMapper courseDetailMapper;
    @Autowired
    private CourseResourceMapper courseResourceMapper;
    @Autowired
    private CourseTypeMapper courseTypeMapper;
    @Autowired//es的仓库
    private EsCourseRepository repository;

    @Override
    public PageList<EsCourse> queryCourseEs(CourseQuery query) {
        return dsl(query);
    }

    /**
     * 查询与过滤
     * @param query
     * @return
     */
    private PageList<EsCourse> dsl(CourseQuery query) {
        NativeSearchQueryBuilder builder = new NativeSearchQueryBuilder();
        /**
         *    keyword
         *     private Long courseType;
         *     private Long tenantId;
         *     private Float priceMin;
         *     private Float priceMax;
         *
         */
        //1 查询+过滤
        BoolQueryBuilder bool = QueryBuilders.boolQuery(); //query bool
        if (StringUtils.hasLength(query.getKeyword())){
            bool.must(QueryBuilders.matchQuery("all",query.getKeyword())); //query bool must match
        }
        if (query.getCourseType()!=null){

            bool.filter(QueryBuilders.matchQuery("courseTypeId",query.getCourseType()));//query bool filter
        }
        if (query.getTenantId()!=null){

            bool.filter(QueryBuilders.matchQuery("tenantId",query.getTenantId()));//query bool filter
        }
        if (query.getPriceMax()!=null && query.getPriceMin()!=null){
            bool.filter(QueryBuilders.rangeQuery("price").gte(query.getPriceMin()).lte(query.getPriceMax()));//query bool filter
        }
        builder.withQuery(bool);
        //2 排序

        if (StringUtils.hasLength(query.getSortType()) && StringUtils.hasLength(query.getSortMethod())){
            SortOrder defaluSortOrder = SortOrder.DESC;
            if (query.getSortMethod().equals("ASC")){
                defaluSortOrder = SortOrder.ASC;
            }
            if (query.getSortType().equals("jg")){

                builder.withSort(SortBuilders.fieldSort("price").order(defaluSortOrder));//通过age倒序排列
            }
            if (query.getSortType().equals("xp")){

                builder.withSort(SortBuilders.fieldSort("startTime").order(defaluSortOrder));//通过age倒序排列
            }
            //.....
        }
        //3 分页
        builder.withPageable(PageRequest.of(query.getPage()-1,query.getRows()));//当前页，每页显示多少个。
        //4 截取字段
//        builder.withSourceFilter(new FetchSourceFilter(new String[]{"name","age","id"},
//                null));
        //5 获取
        Page<EsCourse> page = repository.search(builder.build());
        System.out.println("总页数:"+page.getTotalPages());
        System.out.println("总数:"+page.getTotalElements());
        return new PageList<>(page.getTotalElements(),page.getContent());
    }
    @Override//上线 添加索引库 修改数据库的状态
    public void onLineOrOffLine(List<Long> ids, int flag) {
        if(flag==0){//如果标记是0 就是上线
            //通过ids获取es课程
            List<EsCourse> esCourses=getEsCourses(ids);
            //添加到索引库
            repository.saveAll(esCourses);
            //修改数据库状态
            //update t_course set status=1,onLineTime=#{} where id in (2,3)
            Map<String,Object> params=new HashMap<>();
            params.put("onLineTime",new Date());
            params.put("ids",ids);
            //调用上线方法 将这些上线
            courseMapper.onLine(params);
        }else {
            //标记是1表示下线 删除索引库数据 修改数据库的状态和下线时间
            for(Long id:ids){
                //删除索引库的数据
                repository.deleteById(id);
                //修改数据库的状态
            }
            //修改数据库状态和下架的时间
            // //update t_course set status=0,onLineTime=#{} where id in (2,3)
            Map<String,Object> params=new HashMap<>();
            params.put("offLineTime",new Date());
            params.put("ids",ids);
            //调用下架方法 将这些下架
            courseMapper.offLine(params);
        }
    }
    /**
     * 申明 转换 返回
     * @param ids
     * @return
     */
    private List<EsCourse> getEsCourses(List<Long> ids) {
        //申明一个escourse集合
        List<EsCourse> result=new ArrayList<>();
        //转换 将课程集合查出来
        List<Course> courses=courseMapper.selectBatchIds(ids);
        //遍历课程集合
        for (Course course :courses){
            //把课程转换成es课程 调用course2esCourse方法
            result.add(course2esCourse(course));
        }
        //返回
        return result;
    }
    /**
     * 类型转换方法
     * @param course
     * @return
     */
    private EsCourse course2esCourse(Course course) {
        //申明
        EsCourse result=new EsCourse();
        //转换 将课程的内容存到es
        result.setId(course.getId());
        result.setName(course.getName());
        result.setUsers(course.getUsers());
        //获取课程类型id
        Long courseTypeId = course.getCourseTypeId();
        result.setCourseTypeId(courseTypeId);

        //type 没有做关联查询
        if(courseTypeId!=null){
            //根据课程类型id获取到课程类型名称
            String typeName = courseTypeMapper.selectById(courseTypeId).getName();
            //将课程类型名称设置到es
            result.setCourseTypeName(typeName);
        }
        result.setGradeId(course.getGrade());
        result.setGradeName(course.getGradeName());
        result.setStatus(course.getStatus());
        result.setTenantId(course.getTenantId());
        result.setTenantName(course.getTenantName());
        result.setUserId(course.getUserId());
        result.setUserName(course.getUserName());
        result.setStartTime(course.getOnlineTime());
        result.setEndTime(course.getOfflineTime());

        //Detail 查询是在all里面
        List<CourseDetail> courseDetails = courseDetailMapper.selectList(
                new EntityWrapper<CourseDetail>().eq("course_id",course.getId()));
        if(courseDetails!=null && courseDetails.size()>0){
            result.setIntro(courseDetails.get(0).getIntro());
        }
        //resource
        List<CourseResource> courseResources=courseResourceMapper.selectList(
                new EntityWrapper<CourseResource>().eq("course_id",course.getId())
        );
        if(courseResources!=null && courseResources.size()>0){
            result.setResources(courseResources.get(0).getResources());
        }
        //market 先根据课程id查询出所有的课程市场
        List<CourseMarket> courseMarkets=courseMarketMapper.selectList(
                new EntityWrapper<CourseMarket>().eq("course_id",course.getId()));
        if(courseMarkets!=null&&courseMarkets.size()>0){
            //根据外键查出的课程市场其实只有一个 所以get(0)
            CourseMarket courseMarket=courseMarkets.get(0);
            result.setExpires(courseMarket.getExpires());
            result.setPrice(new BigDecimal(courseMarket.getPrice()));
            result.setPriceOld(new BigDecimal(courseMarket.getPriceOld()));
            result.setQq(courseMarket.getQq());
        }
        return result;
    }

    //重写新增方法
    @Override
    public boolean insert(Course entity) {
        //目前先把用户写死
        Long userId=42L;
        Long tenantId=26L;
        entity.setUserId(userId);
        entity.setTenantId(tenantId);
        //设置课程状态是下线
        entity.setStatus(0);
        //先保存自身表的内容
        //再保存关联表中的内容
        if(entity.getCourseResource()!=null){
            entity.setPic(entity.getCourseResource().getResources().split(",")[0]);
            courseMapper.insert(entity);
        }
        //保存关联表 detail market resource
        if(entity.getCourseDetail()!=null){
            entity.getCourseDetail().setCourseId(entity.getId());
            courseDetailMapper.insert(entity.getCourseDetail());
        }
        if(entity.getCourseMarket()!=null){
            entity.getCourseMarket().setCourseId(entity.getId());
            courseMarketMapper.insert(entity.getCourseMarket());
        }
        if(entity.getCourseResource()!=null){
            entity.getCourseResource().setCourseId(entity.getId());
            courseResourceMapper.insert(entity.getCourseResource());
        }


        return true;
    }

    @Override//同步删除
    public boolean deleteById(Serializable id) {
        //先删除关联表的数据
        courseDetailMapper.delete(new EntityWrapper<CourseDetail>().eq("course_id",id));
        courseResourceMapper.delete(new EntityWrapper<CourseResource>().eq("course_id",id));
        courseMarketMapper.delete(new EntityWrapper<CourseMarket>().eq("course_id",id));
        //根据id查询出课程 等把es库中的数据删了再删自身表里的数据
        Course course = courseMapper.selectById(id);
        //获取课程的状态 如果是上线就删除es库中的数据
        if(course.getStatus()==1){
            //删除es库里的数据
            repository.deleteById(course.getId());
        }
        //删除数据库里的数据
        courseMapper.deleteById(id);
        return true;
    }

    @Override//同步修改
    public boolean updateById(Course entity) {
        //先修改关联表的数据
        courseDetailMapper.updateById(entity.getCourseDetail());
        courseResourceMapper.updateById(entity.getCourseResource());
        courseMarketMapper.updateById(entity.getCourseMarket());
        courseMapper.updateById(entity);
        //根据id查询出课程 等把es库中的数据修改再修改自身表里的数据
        Course course = courseMapper.selectById(entity.getId());
        //如果是上线的课程，需要同步索引库
        if(course.getStatus()==1){
            //把课程转换成es课程course2esCourse
            EsCourse esCourse=course2esCourse(course);
            //课程有id就可以设置到es库中
            esCourse.setId(course.getId());
            repository.save(esCourse);
        }
        return true;
    }


}
